package com.lgc.javathread.forkJoinPoolTest;

import java.sql.SQLOutput;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;

//我们可以定义一个类，去继承RecursiveAction或者是RecursiveTask，这个两个都是抽象类，有一个抽象方法compute()，
// 他们之间的区别在于，前者是没有返回值的，后者是有返回值的，有点像是Runnable和Callable的关系。
public class ForkJoinCalculator {
    static class ForkJoinCalculatorTask extends RecursiveTask<Long> {
        private long start;
        private long end;
        private static final long THRESHOLD = 10000;// 临界值(这个值可以换，比如2或100都可)

        public ForkJoinCalculatorTask(long start, long end) {
            this.start = start;
            this.end = end;
        }

        @Override
        protected Long compute() {
            if (end - start <= THRESHOLD) {// 不大于临界值直接计算和
                long sum = 0;
                for (long i = start; i <= end; i++) {
                    sum += i;
                }

                return sum;
            } else {// 大于临界值继续进行拆分子任务
                long mid = (end + start) / 2;

                // 拆分子任务
                ForkJoinCalculatorTask forkJoin1 = new ForkJoinCalculatorTask(start, mid);
                forkJoin1.fork();
                // 拆分子任务
                ForkJoinCalculatorTask forkJoin2 = new ForkJoinCalculatorTask(mid + 1, end);
                forkJoin1.fork();

                //合并子任务结果
                return forkJoin1.join() + forkJoin2.join();
            }
        }
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ForkJoinPool forkJoinPool=new ForkJoinPool();
        ForkJoinCalculatorTask task=new ForkJoinCalculatorTask(1,10002);
        //第一种调用方式
//        Long sum = forkJoinPool.invoke(task);
//        System.out.println(sum);

        //第二种调用方式
        Future<Long> result = forkJoinPool.submit(task);
        System.out.println(result.get());

        System.out.println("asd");

    }
}
